package org.itt.cp.pec;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.itt.FooUtil;
import org.itt.Properties;
import org.itt.ap.PECMap;
import org.itt.ap.Reader;
import org.itt.ap.Source;

public class PECReader implements Reader {
        private static Logger logger = Logger.getLogger("PECReader");
       
        public static void printProgBar(long l){
            StringBuilder bar = new StringBuilder("[");

            for(int i = 0; i < 50; i++){
                if( i < (l/2)){
                    bar.append("=");
                }else if( i == (l/2)){
                    bar.append(">");
                }else{
                    bar.append(" ");
                }
            }

            bar.append("]   " + l + "%     ");
            System.out.print("\r" + bar.toString());
        }
       
        @Override
        public void parse(Source source) {
                int counter = 0;
                String line;
                BufferedReader br = null;
                PEC pec = null;
                long progress = 0;
                int father = 0;
                int child = 0;
                int rootDir = 0;
               
                try {
                        PECMap map = new PECMap();
                        logger.debug("Istanzio una hashmap di oggetti PEC");
                       
                        long fileSize = new File(Properties.get().WORKDIR + File.separator + Properties.get().SOURCE).length();
                        logger.debug("File sorgente: " + Properties.get().WORKDIR + File.separator + Properties.get().SOURCE + " - dimensione: " + fileSize + " bytes");
                       
                        br = new BufferedReader(new FileReader(Properties.get().WORKDIR + File.separator + Properties.get().SOURCE));
                        logger.info("Mi preparo a leggere il file sorgente: " + Properties.get().WORKDIR + File.separator + Properties.get().SOURCE);
                       
                        long start = System.nanoTime();
                       
                        while ((line = br.readLine()) != null) {
                                progress += line.length();
                                printProgBar(progress*100/fileSize);
                               
                                // A new PEC object
                                pec = new PEC();
                               
                                String[] pecArray = new String[Integer.valueOf(Properties.get().MAX_COLUMN_SIZE)];
                               
                                // Separo le colonne della riga utilizzando il separatore specificato nel file di properties
                                String[] row = line.split(Properties.get().SPLIT_BY);
                               
                                for(int i=0; i<pecArray.length; i++) {
                                        pecArray[i] = "";
                                }
                               
                                for(int i=0; i<row.length; i++) {
                                        pecArray[i] = row[i];
                                }
                               
                                // Il controllo sulla lunghezza dell'array serve per evitare di parsare le righe dell'index.dat
                                // contenenti solo il path della directory contenente le PEC
                                if(row.length > 1 && map.get(pecArray[0]) == null) {
                                        father++;                                      
                                        // Inizio il parsing di tutte le colonne dell'index.dat
                                       
                                        /* PATH_FILE */
                                        pec.setPathFile(pecArray[0]);
                                       
                                        /* CLIENTE */
                                        pec.setCliente(pecArray[1]);
                               
                                        /* MAILBOX */
                                        pec.setMailbox(pecArray[2]);
                                       
                                        /* MESE */
                                        pec.setMese(pecArray[3]);
                                       
                                        /* ANNO */
                                        pec.setAnno(pecArray[4]);
                                       
                                        /* TIPO_MESSAGGIO */
                                        pec.setTipoMessaggio(pecArray[5]);
                                       
                                        /* MITTENTE */
                                        pec.setMittente(pecArray[6]);
                                       
                                       
                                        /* DESTINATARIO */
                                        pec.addDestinatario(pecArray[7]);
                                       
                                        /* TIPO_DESTINATARIO */
                                        pec.addTipoDestinatario(pecArray[8]);
                               
                                        /* OGGETTO */
                                        pec.setOggetto(pecArray[9]);
       
                                        /* TIMEZONE */
                                        pec.setTimezone(pecArray[10]);
                                       
                                        /* DATA */
                                        if(pecArray[11] == "") {
                                                pec.setData(null);
                                        } else {                                                
                                                pec.setData(new SimpleDateFormat("dd/MM/yyyy").parse(pecArray[11]));
                                        }
                                       
                                        /* ORA */
                                        if(pecArray[12] == "") {
                                                pec.setOra(null);
                                        } else {                                                
                                                pec.setOra(new SimpleDateFormat("HH:mm:ss").parse(pecArray[12]));
                                        }
                                       
                                        /* IDENTIFICATIVO_MSGID */
                                        pec.setIdentificativoMsgId(pecArray[13]);
                                       
                                        /* RISPOSTE */
                                        pec.addRisposte(pecArray[14]);
                                       
                                        /* RIFMSGID */
                                        pec.setRifMsgId(pecArray[15]);
                       
                                        /* TIPO_RICEVUTA */
                                        pec.setTipoRicevuta(pecArray[16]);
                                       
                                        /* CONSEGNA */
                                        pec.addConsegna(pecArray[17]);
                                       
                                        /* RICEZIONE */
                                        if(pecArray.length > 18)
                                                pec.addRicezione(pecArray[18]);
                                       
                                        // Dichiaro una lista di oggetti PEC. Una lista contiene gli oggetti PEC relativi ad una sola mail.
                                        // Le n righe ripetute (multi-indice) rappresentano n oggetti PEC che finiscono in una lista PEC
                                        List<Source> values = null;
                                       
                                        /* PATH_FILE_FATHER */
                                        values = new ArrayList<Source>();
                                       
                                        // Aggiungo l'oggetto PEC alla lista di oggetti PEC
                                        values.add(pec);
                                       
                                        // Aggiungo la lista di oggetti PEC alla hashmap, specificando come chiave il nome univoco della mail
                                        map.put(pecArray[0], values);
                                } else if(row.length > 1 && map.get(pecArray[0]) != null) {
                                        List<Source> values = map.get(pecArray[0]);
                                        PEC p = (PEC) values.get(0);
                                        p.setPathFileFather(pecArray[0]);
                                        p.addDestinatario(pecArray[7]);
                                        p.addTipoDestinatario(pecArray[8]);
                                        p.addRisposte(pecArray[14]);
                                        p.addConsegna(pecArray[17]);
                                       
                                        if(pecArray.length > 18) {
                                                p.addRicezione(pecArray[18]);
                                        }
                                       
                                        child++;
                                } else {
                                        rootDir++;
                                }
                               
                                // Incremento il contatore per il ciclo while
                                counter++;
                        }
                       
                        printProgBar(100);
                       
                        System.out.print("\n");
                       
                        logger.info("Ho letto " + counter + " righe: " + rootDir + " directory, " + father + " padri, " + child + " figli");
                        logger.info("Durata lettura: " + FooUtil.prettyPrintTime(System.nanoTime() - start));

                        source.setPECMap(map);
                        logger.debug("Finalizzo la hashmap di oggetti PEC");
                } catch (NumberFormatException | IOException | ParseException e) {
                        logger.error(e);
                        System.exit(1);
                } finally {
                        if (br != null) {
                                try {
                                        br.close();
                                } catch (IOException e) {
                                        logger.error(e);
                                }
                        }
                }
        }
}
